package com.sun.mongodb.core.params;

import com.sun.mongodb.core.ex.ParamDefectException;
import com.sun.mongodb.core.reflection.ReflectionUtil;
import com.sun.mongodb.core.reflection.SerializableFunction;
import com.sun.mongodb.core.util.SpringContextHolder;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;

/**
 * Created by Administrator on 2021/9/6.
 */
@Data
public class LookUpParam {
    /**
     * 关联表名
     */
    private String from;
    /**
     * 关联字段
     */
    private String localField;
    /**
     * 关联表联字段
     */
    private String foreignField;
    /**
     * 返回别名
     */
    private String as;


//    public LookUpParam form(Class<?> clazz){
//        this.from =  BeanUtil.getBean(MongoTemplate.class).getCollectionName(clazz);
//        return this;
//    }
//
//    public <E,R> LookUpParam localField(SerializableFunction<E,R> localField){
//        this.localField = ReflectionUtil.getFieldName(localField);
//        return this;
//    }
//    public <E,R> LookUpParam foreignField(SerializableFunction<E,R> foreignField){
//        this.foreignField = ReflectionUtil.getFieldName(foreignField);
//        return this;
//    }
//    public <E,R> LookUpParam as(SerializableFunction<E,R> as){
//        this.as = ReflectionUtil.getFieldName(as);
//        return this;
//    }

    /**
     * 构建builder对象
     * @return
     */
    public static LookUpParam.Builder builder(){
        return new Builder();
    }

    public static class Builder {
        /**
        * 关联表名
        */
        private Class<?> from;
        /**
         * 关联字段
         */
        private SerializableFunction localField;
        /**
         * 关联表联字段
         */
        private SerializableFunction foreignField;
        /**
         * 返回别名
         */
        private SerializableFunction as;

        public Builder form(Class<?> clazz){
            this.from =  clazz;
            return this;
        }

        public <E,R> Builder localField(SerializableFunction<E,R> localField){
            this.localField =localField;
            return this;
        }
        public <E,R> Builder foreignField(SerializableFunction<E,R> foreignField){
            this.foreignField = foreignField;
            return this;
        }
        public <E,R> Builder as(SerializableFunction<E,R> as){
            this.as =as;
            return this;
        }

        public LookUpParam build() {
           return new LookUpParam(this);
        }
    }

    private LookUpParam(Builder b){
        MongoTemplate mongoTemplate= SpringContextHolder.getBean(MongoTemplate.class);
        this.from =  mongoTemplate.getCollectionName(b.from);
        this.localField =  ReflectionUtil.getFieldName(b.localField);
        this.foreignField =  ReflectionUtil.getFieldName(b.foreignField);
        this.as =  ReflectionUtil.getFieldName(b.as);
    }


    public AggregationOperation buildAggregationOperation(){
        return Aggregation.lookup( this.getFrom(), this.getLocalField(),this.getForeignField(), this.getAs() );
    }

    public void check(){
        if(StringUtils.isBlank(this.getFrom())){
            throw new ParamDefectException("LookUpParam.check()检查到->参数[from]缺失");
        }
        if(StringUtils.isBlank(this.getLocalField())){
            throw new ParamDefectException("LookUpParam.check()检查到->参数[localField]缺失");
        }
        if(StringUtils.isBlank(this.getForeignField())){
            throw new ParamDefectException("LookUpParam.check()检查到->参数[foreignField]缺失");
        }
        if(StringUtils.isBlank(this.getAs())){
            throw new ParamDefectException("LookUpParam.check()检查到->参数[as]缺失");
        }
    }
}
